package com.peas.platform.common.core.utils;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.peas.platform.common.core.configuration.DateFormatReg;
import lombok.extern.slf4j.Slf4j;

import javax.validation.*;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.*;

/**
 * @author caizhh
 */
@Slf4j
public class ValidatorUtil {

    public static <T> void validateList(@Valid List<T> objs) {
        validateCollection(objs);
    }

    public static <T> void validateSet(@Valid Set<T> objs) {
        validateCollection(objs);
    }

    public static <T> void validateCollection(@Valid Collection<T> objs) {
        if (CollUtil.isEmpty(objs)) {
            return;
        }
        for (T obj : objs) {
            validateObj(obj);
        }
    }

    public static <T> void validateObj(@Valid T obj) {
        try (ValidatorFactory factory = Validation.buildDefaultValidatorFactory()) {
            Validator validator = factory.getValidator();
            Map<String, String> validatedMsg = new HashMap<>();
            Set<ConstraintViolation<T>> constraintViolations = validator.validate(obj);
            for (ConstraintViolation<T> c : constraintViolations) {
                validatedMsg.put(c.getPropertyPath().toString(), c.getMessage());
            }
            if (CollUtil.isNotEmpty(validatedMsg)) {
                log.error("validate, validatedMsg:" + validatedMsg + ", obj:" + JSONUtil.toJsonStr(obj));
                throw new IllegalArgumentException(validatedMsg.values().toString());
            }
        }
    }

    public static void checkFieldValue(Field f, String v, String label) {
        if (StrUtil.isBlank(label)) {
            label = f.getName();
        }
        NotBlank notBlank = f.getAnnotation(NotBlank.class);
        NotNull notNull = f.getAnnotation(NotNull.class);
        Size size = f.getAnnotation(Size.class);
        if (notBlank != null || notNull != null) {
            Assert.notBlank(v, label + "不能为空");
        }
        Class<?> type = f.getType();
        if (type == String.class) {
            if (size != null) {
                Assert.isTrue(StrUtil.length(v) <= size.max(), label + "长度不能超过" + size.max());
            }
        }
        if (type == Long.class || type == Integer.class) {
            Assert.isTrue(NumberUtil.isInteger(v) || NumberUtil.isLong(v), label + "必须是整数");
        }
        if (type == BigDecimal.class || type == Float.class || type == Double.class) {
            Assert.isTrue(NumberUtil.isNumber(v), label + "必须是数字");
        }
        if (type == Date.class) {
            Assert.isTrue(DateFormatReg.checkFormat(v), label + "的格式不是日期/时间格式");
        }
    }

}
